package com.android.project.games;

import java.util.List;

import javax.microedition.khronos.opengles.GL10;

import android.database.Cursor;
import android.os.Message;
import android.os.Vibrator;
import android.util.Log;
import android.view.inputmethod.InputMethodManager;

import com.android.project.framework.Game;
import com.android.project.framework.Input.KeyEvent;
import com.android.project.framework.Input.TouchEvent;
import com.android.project.framework.gl.Camera2D;
import com.android.project.framework.gl.SpriteBatcher;
import com.android.project.framework.impl.GLGame;
import com.android.project.framework.impl.GLScreen;
import com.android.project.framework.impl.ViewGame;
import com.android.project.framework.math.OverlapTester;
import com.android.project.framework.math.Rectangle;
import com.android.project.framework.math.Vector2;
import com.android.project.framework.util.DbAdapter;
import com.android.project.games.World.WorldListener1;
import com.android.project.mysql.connection.AssociationWord;
import com.android.project.mysql.connection.ConnectionData;

public class GameScreen extends GLScreen {
	static final int GAME_READY = 0;
	static final int GAME_RUNNING = 1;
	static final int GAME_PAUSED = 2;
	static final int GAME_LEVEL_END = 3;
	static final int GAME_OVER = 4;
	int state;
	Camera2D guiCam;
	Vector2 touchPoint;
	SpriteBatcher batcher;
	
	ViewGame view;
	String stringa = "";
	World world;
	WorldListener1 listener;
	WorldRenderer renderer;
	Vector2 position;
	List<TouchEvent> touchList;
	boolean keyboardShow = false;
	ConnectionData data;
	List<AssociationWord> listWord;
	Label newLabel;
	Rectangle pauseBounds;
	Rectangle quitBounds;
	Rectangle resumeBounds;
	List<KeyEvent> keyList;
	int prefixL;
	String check;
	InputMethodManager  m;
	Vibrator c;
	int result;

	int lastScore;
	//int over = 0;
	static int level;
	int score;
	float timeDown;
	boolean isTouchDown;
	boolean isDragged;
	Rectangle rightBounds;
	Rectangle wrongBounds;
	//List<AssociationWords> listAss;
	

	private DbAdapter dbHelper; 
	private Cursor cursor;
	
	public GameScreen(Game game) {
		super(game);
		// TODO Auto-generated constructor stub
		state = GAME_READY;
		guiCam = new Camera2D(glGraphics, 320, 480);
		touchPoint = new Vector2();
		position = new Vector2();
		batcher = new SpriteBatcher(glGraphics, 1000);
		view = glGraphics.getGlView();
		data = new ConnectionData();
		listener = (new WorldListener1() {
			
			@Override
			public void wrong() {
				// TODO Auto-generated method stub
				Assets.playSound(Assets.wrongSound);
			}
			
			@Override
			public void right() {
				// TODO Auto-generated method stub
				Assets.playSound(Assets.rightSound);
				
			}
			
			@Override
			public void semi() {
				// TODO Auto-generated method stub
				Assets.playSound(Assets.semiSound);
			}
			
		
		});
		level = 1;		
		listWord = data.retrieveData("-1");
		m = (InputMethodManager) glGame.getApplicationContext().getSystemService("input_method");		 
		c = (Vibrator) glGame.getApplicationContext().getSystemService("vibrator");
		world = new World(listener, listWord.get(0).getWord(), level);
		renderer = new WorldRenderer(glGraphics, batcher, world);
	    pauseBounds = new Rectangle(320- 32, 480- 32, 32, 32);
	    quitBounds = new Rectangle(160 - 150, 300 - 18, 300, 36);    
	    resumeBounds = new Rectangle(160 - 150, 300 - 40 , 300, 36);
	    
	    rightBounds = new Rectangle(100 - 24, 160 - 24, 48, 48);
	    wrongBounds = new Rectangle(240 - 26, 160 - 26, 48, 48);
		score = 0;
		
		//listAss = AssociationIO.load(game.getFileIO());
		
		 dbHelper = new DbAdapter(glGame);
		
		
		 
	     
	}

	@Override
	public void update(float deltaTime) {
		// TODO Auto-generated method stub
	
		switch(state){
		case GAME_READY:
			updateReady();
			break;
		case GAME_RUNNING:
			updateRunning(deltaTime);
			break;
		case GAME_PAUSED:
			updatePaused(deltaTime);
			break;
		case GAME_LEVEL_END:
			updateLevelEnd();
			break;
		case GAME_OVER:
			updateGameOver();
			break;
		}
		
	}

	private void updateReady() {
		// TODO Auto-generated method stub
		touchList = game.getInput().getTouchEvents();
		for (int i = 0; i < touchList.size(); i++){
			TouchEvent event = touchList.get(i);
			if(event.type == TouchEvent.TOUCH_UP )
				state = GAME_RUNNING;
				world.state = World2.WORLD_STATE_READY;
			   

		}
		
		
	}

	private void updateRunning(float deltaTime) {
		
		// TODO Auto-generated method stub

		//String w = listWord.get(0).getWord();
		
		//world2.update(deltaTime);
		
		dbHelper.open();
		touchList = game.getInput().getTouchEvents();
		keyList = game.getInput().getKeyEvents();
		
		if(world.score != lastScore){
			lastScore = world.score;
			score = lastScore;
		}
	//	world2.render = 3;
		
		//gestione del tasto indietro
		if(glGraphics.getGlView().isPressBack()){	
			world.pressBack = true;
			glGraphics.getGlView().setPressBack(false);

		
		}
		world.state = World.WORLD_STATE_RUNNING;	
	
		
		for (int i = 0; i < touchList.size(); i++){
			TouchEvent event = touchList.get(i);
			touchPoint.set(event.x, event.y);
			guiCam.touchToWorld(touchPoint);
			
			if(event.type == TouchEvent.TOUCH_UP ){
				world.render = 3;
				if(OverlapTester.pointInRectangle(pauseBounds, touchPoint)){
					Assets.playSound(Assets.clickSound);
					state = GAME_PAUSED;
					m.hideSoftInputFromWindow(view.getWindowToken(), 0);
					world.state = World2.WORLD_STATE_GAME_PAUSED;
				
				}
			}
			else if(event.type == TouchEvent.TOUCH_DRAGGED){
				
				world.positionTouch.set(touchPoint.x, touchPoint.y);
				isTouchDown = false;
				isDragged = true;
				world.render = 1;
				world.keyboardShow = false;
				
				
			}
			else if(event.type == TouchEvent.TOUCH_DOWN){
				/*touchPoint.set(event.x,event.y);
				guiCam.touchToWorld(touchPoint);*/
				world.positionTouchPrev.set(touchPoint.x, touchPoint.y);
			
				isTouchDown = true;
				timeDown = System.nanoTime();
				isDragged = false;
				world.pressBack = false;
				
				
			
			
			}
				
		}
			
			
		
		if(!isDragged && isTouchDown && ((float)(System.nanoTime()) - timeDown) > 500000000 && !world.pressBack){
			c.vibrate(200);
		    m.showSoftInput(view, 0);
		   // world2.pressBack = false;
		    keyboardShow = true;
		    world.state = World.WORLD_STATE_RUNNING;
		    world.keyboardShow = true;
		}
		
		world.update(deltaTime);
		
		if(world.state == World.WORLD_GAME_OVER){
			Settings.addScore(lastScore);
			Settings.save(game.getFileIO());
			state = GAME_OVER;		
			m.hideSoftInputFromWindow(view.getWindowToken(), 0);
			return;
		}
		else if(world.state == World.WORLD_STATE_LEVEL_END){
			Settings.addScore(lastScore);
			Settings.viewScore(lastScore);
			Settings.save(game.getFileIO());
			state = GAME_LEVEL_END;	
			m.hideSoftInputFromWindow(view.getWindowToken(), 0);
			return;
		}
		
		for(int i = 0; i < keyList.size(); i++){
			
			
			KeyEvent event = keyList.get(i);
		
			if(event.type == KeyEvent.KEY_UP){	
				
				if(event.keyCode == 67){
					
					if(stringa.length() > 0){
						prefixL = stringa.length() - 1;
						stringa = stringa.substring(0, prefixL);
					}
					else stringa = "";
					world.enableLabel(stringa);
				}
				else if(event.keyCode == 66){
						boolean update = false;
						
						result = world.checkWord(listWord,glGame);		
						Log.d("GameScreen2 result", "" + result);
						if(result == 0){	
							cursor = dbHelper.fetchAssocByFilter(listWord.get(0).getWord());	
										
							glGame.startManagingCursor(cursor);
							while(cursor.moveToNext()){
								Log.d("database", "" + cursor.getString(cursor.getColumnIndex(DbAdapter.KEY_WORD2)));
								if (cursor.getString(cursor.getColumnIndex(DbAdapter.KEY_WORD2)).equals(listWord.get(1).getId())){
									int peso = Integer.valueOf(cursor.getString(cursor.getColumnIndex(DbAdapter.KEY_PESO))) + 1;
									dbHelper.updateAssoc(cursor.getColumnIndex(DbAdapter.KEY_ID), listWord.get(0).getWord(),  listWord.get(1).getId(), String.valueOf(peso));
			
									update = true;
								}
								
							}
							if(!update) dbHelper.createAssoc(listWord.get(0).getWord(), listWord.get(1).getWord(), String.valueOf(1));
								
							listWord = data.retrieveData(listWord.get(1).getId());		
							cursor.close();
							stringa = "";
							
							//return;
						}
						if(result == -1){ 			
							Message msg = new Message();
							msg.obj = "Hai sbagliato! Continua la catena da " + listWord.get(0).getWord();
							cursor = dbHelper.fetchAssocByFilter(listWord.get(0).getWord());
							
							((GLGame)game).getToastHandler().sendMessage(msg);			
							//return;
							
							glGame.startManagingCursor(cursor);
							while(cursor.moveToNext() ){
								Log.d("database", "" + cursor.getString(cursor.getColumnIndex(DbAdapter.KEY_WORD2)));
								if (cursor.getString(cursor.getColumnIndex(DbAdapter.KEY_WORD2)).equals(stringa)){
									int peso = Integer.valueOf(cursor.getString(cursor.getColumnIndex(DbAdapter.KEY_PESO))) + 1;
									dbHelper.updateAssoc(cursor.getColumnIndex(DbAdapter.KEY_ID), listWord.get(0).getWord(),  listWord.get(1).getWord(), String.valueOf(peso));
									update = true;
								}		
								
							}
							if(!update)dbHelper.createAssoc(listWord.get(0).getWord(), stringa, String.valueOf(1));
							
							listWord = data.retrieveData(listWord.get(0).getId());
							cursor.close();
							stringa = "";
	
						}
						else if(result > 0){
							Message msg = new Message();
							msg.obj = "Ti sei avvicinato! Continua la catena da qui!";
							((GLGame)game).getToastHandler().sendMessage(msg);
							cursor = dbHelper.fetchAssocByFilter(listWord.get(0).getWord());
									
							glGame.startManagingCursor(cursor);
							while(cursor.moveToNext()){
								Log.d("database", "" + cursor.getString(cursor.getColumnIndex(DbAdapter.KEY_WORD2)));
								if (cursor.getString(cursor.getColumnIndex(DbAdapter.KEY_WORD2)).equals(listWord.get(result).getId())){
									int peso = Integer.valueOf(cursor.getString(cursor.getColumnIndex(DbAdapter.KEY_PESO))) + 1;
									dbHelper.updateAssoc(cursor.getColumnIndex(DbAdapter.KEY_ID), listWord.get(0).getWord(),  listWord.get(result).getWord(), String.valueOf(peso));
									update = true;
								}										
								
							}
							if(!update)dbHelper.createAssoc(listWord.get(0).getWord(), stringa, String.valueOf(1));
							
							cursor.close();
							listWord = data.retrieveData(listWord.get(result).getId());			
							stringa = "";
							//return;
							
							
						}
					
				}	
				else{		
					stringa = stringa.concat(String.valueOf(event.keyChar));	
					world.enableLabel(stringa);	
					
				}	
				
			}
 
		}
		
		
		
		dbHelper.close();
	
	}

	private void updatePaused(float deltaTime ) {
		// TODO Auto-generated method stub
		touchList = game.getInput().getTouchEvents();
		int len = touchList.size();
		world.update(deltaTime);
		for(int i = 0; i < len; i++){
			TouchEvent event = touchList.get(i);
			if(event.type == TouchEvent.TOUCH_UP){
				touchPoint.set(event.x, event.y);
				guiCam.touchToWorld(touchPoint);
				if(OverlapTester.pointInRectangle(resumeBounds, touchPoint)){
					Assets.playSound(Assets.clickSound);
					state = GAME_RUNNING;
					return;
				}
				if(OverlapTester.pointInRectangle(quitBounds, touchPoint)){
					Assets.playSound(Assets.clickSound);
					game.setScreen(new MainMenuScreen(game));
					dbHelper.close();
					return;
				}	
			}
			
		}
		
		
	}

	private void updateLevelEnd() {
		// TODO Auto-generated method stub
		touchList = game.getInput().getTouchEvents();
		for(int i = 0; i < touchList.size(); i++){
			TouchEvent event = touchList.get(i);
			if(event.type == TouchEvent.TOUCH_UP){
				touchPoint.set(event.x, event.y);
				guiCam.touchToWorld(touchPoint);
				if(OverlapTester.pointInRectangle(rightBounds, touchPoint)){
					listWord = data.retrieveData("-1");	
					world = new World(listener, listWord.get(0).getWord(), level++);
					renderer = new WorldRenderer(glGraphics, batcher, world);
					world.score = lastScore;
					state = GAME_READY;
					dbHelper.close();
					return;
				}
				else if(OverlapTester.pointInRectangle(wrongBounds, touchPoint)){
					game.setScreen(new SocialScreen(game));
					dbHelper.close();
				}
				
			}
					
		}
		
		
	}

	private void updateGameOver() {
		// TODO Auto-generated method stub
		touchList  = game.getInput().getTouchEvents();
		int len = touchList.size();
		for(int i = 0; i < len; i++) {
			TouchEvent event = touchList.get(i);
			if(event.type != TouchEvent.TOUCH_UP)
				continue;
			game.setScreen(new MainMenuScreen(game));
			dbHelper.close();
		}
		
	}

	@Override
	public void present(float deltaTime) {
		// TODO Auto-generated method stub
		GL10 gl = glGraphics.getGl();
		gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
       
       
        gl.glEnable(GL10.GL_TEXTURE_2D);
        
        renderer.render(stringa);
        
        guiCam.setViewportAndMatrices();
		gl.glEnable(GL10.GL_BLEND);
		gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
		batcher.beginBatch(Assets.items);
		switch(state){
			case GAME_READY:
				presentReady();
				
				break;
			case GAME_RUNNING:
				presentRunning();
				break;
			case GAME_PAUSED:
				presentPaused();
				break;
			case GAME_LEVEL_END:
				presentLevelEnd();
				break;
			case GAME_OVER:
				presentGameOver();
				break;
				
		}
		batcher.endBatch();
		gl.glDisable(GL10.GL_BLEND);
		
	}
		
	

	

	private void presentGameOver() {
		// TODO Auto-generated method stub
		batcher.drawSprite(160, 300,236 ,50, Assets.gameOverRegion);
	}

	

	private void presentReady() {
		// TODO Auto-generated method stub
		//Assets.font.drawText(batcher, "Clicca sullo schermo per iniziare!", x , y);
		batcher.drawSprite(160, 240, 128, 50, Assets.clickRegion);
		
		
	}
	
	private void presentPaused() {
		// TODO Auto-generated method stub
		batcher.drawSprite(160, 300, 300, 36, Assets.quitRegion);
		batcher.drawSprite(160, 300 - 40, 300, 36, Assets.resumeRegion);
		
		
	}
	
	private void presentLevelEnd() {
		// TODO Auto-generated method stub
		batcher.drawSprite(42, 480 - 16 , 79, 24, Assets.scoreRegion);
		Assets.font.drawText(batcher, " "  + String.valueOf(score),90, 480-16);
		batcher.drawSprite(320- 16, 480- 16, 32, 32, Assets.pauseRegion);
		touchList = game.getInput().getTouchEvents();
		
				
		
		batcher.drawSprite(160, 300, 290 ,160, Assets.levelEnd);
		batcher.drawSprite(100, 160, 48, 48, Assets.right);
		batcher.drawSprite(240, 160, 48, 48, Assets.wrong);

		
		
	}
	
	private void presentRunning() {
		// TODO Auto-generated method stub
		batcher.drawSprite(42, 480 - 16 , 79, 24, Assets.scoreRegion);
		Assets.font.drawText(batcher, " "  + String.valueOf(score),90, 480-16);
		batcher.drawSprite(320- 16, 480- 16, 32, 32, Assets.pauseRegion);
	
		
	}

	@Override
	public void pause() {
		// TODO Auto-generated method stub
		if(state == GAME_RUNNING)
			state = GAME_PAUSED;
		
	}

	@Override
	public void resume() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void dispose() {
		// TODO Auto-generated method stub
		
	}

}
